package com.atguigu.tingshu.common.aspect;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.anno.GuiGuLogin;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Component
@Aspect
public class GuiGuLoginAspect {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Around(value = "@annotation(guiGuLogin)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, GuiGuLogin guiGuLogin){
        //获取ServletRequestAttributes对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //通过ServletRequestAttributes对象获取requect
        HttpServletRequest request = requestAttributes.getRequest();
        //通过requect获取token
        String token = request.getHeader("token");
        //完成用户登录的校验
        if(guiGuLogin.required()){
            //判断token是否存在
            if(StringUtils.isEmpty(token)){
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
            //存在token
            extracted(token);

        }else{
            if (!StringUtils.isEmpty(token)) {
                extracted(token);
            }
        }
        try {
            //调用方法
           return proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
            if(e instanceof GuiguException){
                throw (GuiguException)e;
            }else{
                throw new RuntimeException(e);
            }
        }finally {
            //防止内存泄漏所以用完之后及时删除
            AuthContextHolder.removeUserId();
            AuthContextHolder.removeUsername();
        }

    }

    private void extracted(String token) {
        String userInfoRedisKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
        String userInfoJson = stringRedisTemplate.opsForValue().get(userInfoRedisKey);
        //检验token的合法性
        if (!StringUtils.isEmpty(userInfoJson)) {
            //解析json数据 然后把数据存储到threadlocal中
            UserInfo userInfo = JSON.parseObject(userInfoJson, UserInfo.class);
            Long id = userInfo.getId();

            String nickname = userInfo.getNickname();
            AuthContextHolder.setUserId(id);
            AuthContextHolder.setUsername(nickname);
        }
    }

}
